package com.gyg.service.impl;

import cn.hutool.core.lang.Dict;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONUtil;
import com.aliyuncs.CommonRequest;
import com.aliyuncs.CommonResponse;
import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.IAcsClient;
import com.aliyuncs.exceptions.ClientException;
import com.aliyuncs.exceptions.ServerException;
import com.aliyuncs.http.MethodType;
import com.aliyuncs.profile.DefaultProfile;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.gyg.constant.RedisConstants;
import com.gyg.domain.CloudMsg;
import com.gyg.dao.CloudMsgMapper;
import com.gyg.domain.CloudUser;
import com.gyg.returns.RespCode;
import com.gyg.returns.RespEntity;
import com.gyg.service.CloudMsgService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.gyg.service.CloudUserService;
import com.gyg.utils.RedisUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.util.Map;
import java.util.Objects;

/**
 * <p>
 * 短信验证码表 服务实现类
 * </p>
 *
 * @author gyg
 * @since 2021-02-20
 */
@Service
@Slf4j
public class CloudMsgServiceImpl extends ServiceImpl<CloudMsgMapper, CloudMsg> implements CloudMsgService {

    @Autowired
    private CloudUserService cloudUserService;

    @Autowired
    private RedisUtil redisUtil;

    @Value("${cloud.sms.url}")
    private String url;

    @Value("${cloud.sms.username}")
    private String username;

    @Value("${cloud.sms.password}")
    private String password;


    @Override
    public RespEntity<Integer> sendMsg(String mobile) {
        //校验手机号是否被注册
        CloudUser cloudUser = getCloudUser(mobile);
        if (Objects.nonNull(cloudUser)) {
            return new RespEntity<>(RespCode.MOBILE_ERROR);
        }

        //随机生成6位数字验证码
        String code = RandomUtil.randomNumbers(6);
        //发送短信验证码
        String send = send(mobile, code);
        if (Objects.isNull(send)) {
            return new RespEntity<>(RespCode.PHONE_ERROR);
        }
        //获取短信验证码 间隔时间
        Integer time = getSMSTime();
        //code保存redis 并设置过期时间
        redisUtil.set(RedisConstants.key.getSms(mobile), code, time);

        return new RespEntity(RespCode.SUCCESS, time);
    }

    /**
     * 获取cloudUser
     * @param mobile
     * @return
     */
    private CloudUser getCloudUser(String mobile) {
        QueryWrapper<CloudUser> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(CloudUser::getMobile, mobile);
        return cloudUserService.getOne(queryWrapper);
    }

    /**
     * 获取短信验证码间隔时间
     * @return
     */
    private Integer getSMSTime() {
        QueryWrapper<CloudMsg> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(CloudMsg::getDeleted, 0);
        CloudMsg cloudMsg = baseMapper.selectOne(queryWrapper);
        if (Objects.isNull(cloudMsg)) {
            cloudMsg = new CloudMsg();
            cloudMsg.setTime(60);
        }
        return cloudMsg.getTime();
    }

    /**
     * 发送短信验证码
     * @param mobile
     * @param code
     * @return
     */
    private String send(String mobile, String code) {

        String content = template(mobile, code);
        log.info("发送短信模板为：content={}", content);

        String smsUrl = url + "?username=" + username + "" +
                "&password=" + password + "&mobile=" + mobile + "&content=" + content;

        String response = HttpUtil.get(smsUrl);
        log.info("短信发送数据返回，response={}", response);

        Map respMap = JSONUtil.toBean(response, Map.class);
        Integer result = (Integer) respMap.get("result");
        if (result.equals(0)) {
            return "OK";
        }
        return null;
    }

    private String template(String mobile, String code) {
        String template = "您的手机号：{}，注册验证码：{}，一分钟内提交有效，如不是本人操作请忽略！【CloudBox云盘】";
        return StrUtil.format(template, mobile, code);
    }

}
